﻿/**
 * @file Account.h
 * @author monster
 * @date 2024/4/4
 */

#pragma once

#include <stdint.h>
#include <vector>
#include "PingPongBuffer/PingPongBuffer.h"

#define ACCOUNT_DISCARD_READ_DATA   1


class DataCenter;

class Account {
public:

    /* Event type enumeration */
    typedef enum {
        EVENT_NONE,
        EVENT_PUBLISH,  // Publisher posted information
        EVENT_PULL,     // Subscriber data pull request
        EVENT_NOTIFY,   // subscribers send notifications to publishers
        EVENT_TIMER,    // Timed event
        _EVENT_LAST
    } EventCode_t;

    /* Return result type enumeration */
    typedef enum {
        RES_OK                  = 0,
        RES_UNKNOWN             = -1,
        RES_SIZE_MISMATCH       = -2,
        RES_UNSUPPORTED_REQUEST = -3,
        RES_NO_CALLBACK         = -4,
        RES_NO_BUFFER           = -5,
        RES_NO_COMMIT           = -6,
        RES_NOT_FOUND           = -7,
        RES_PARAM_ERROR         = -8
    } ResCode_t;

    /*Descriptor of event parameter*/
    typedef struct {
        EventCode_t event;      /*Event code type*/
        Account     *tran;      /*Pointer to sender*/
        Account     *recv;      /*Pointer to receiver*/
        void        *data;      /*Pointer to data*/
        uint32_t    size;       /*The length of the data*/
    } EventParams_t;


    /*Event execute this type of functions.*/
    typedef int(*EventCallback_t)(Account *user, EventParams_t *param);

    typedef std::vector<Account *> AccountVector_t;

public:
    Account(const char *id, DataCenter *center,
            uint32_t size = 0, void *user_data = nullptr);

    ~Account();

    void SetEventCallback(EventCallback_t callback);
    Account *Subscribe(const char *id);
    bool Unsubscribe(const char *pubID);

    bool Commit(void *data, uint32_t size);
    int Publisher();
    int Pull(const char *pubID, void *data, uint32_t size);
    int Pull(Account *pub, void *data, uint32_t size);
    int Notify(const char *pubID, void *data, uint32_t size);
    int Notify(Account *pub, void *data, uint32_t size);
public:
    const char *ID;         /* Unique account ID */
    DataCenter *Center;    /* Pointer to the data center */
    void       *UserData;

    AccountVector_t publishers;
    AccountVector_t subscribers;

    EventCallback_t eventCallback;
    PingPongBuffer  Buffer;
};

